﻿using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Camc.Quality.Authorization.Roles;
using Camc.Quality.Authorization.Roles.Dto;
using System;
using System.Collections.Generic;
using Abp.Linq.Extensions;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Camc.Quality.Chat;
using Camc.Quality.Bop.IbopInterface;
using Camc.Quality.Bop.TreeObject;
using System.Reflection;
using System.ComponentModel;
using Abp.Authorization.Users;
using Camc.Quality.Common;

namespace Camc.Quality.WorkFlow
{
    public class AffairRemindAppService : QualityAppServiceBase
    {
        private readonly IRoleAppService _iRoleAppService;
        private readonly IRepository<AffairRemind, int> _affairRemindRepository;
        private readonly IRepository<AffairMessage, Guid> _affairMessageRepository;
        private readonly IRepository<UserRole, long> _userRoleRepository;
        public AffairRemindAppService(IRepository<AffairRemind, int> affairRemindRepository,
            IRoleAppService iRoleAppService,
            IRepository<AffairMessage, Guid> affairMessageRepository,
            IRepository<UserRole, long> userRoleRepository)
        {
            _affairRemindRepository = affairRemindRepository;
            _iRoleAppService = iRoleAppService;
            _affairMessageRepository = affairMessageRepository;
            _userRoleRepository = userRoleRepository;
        }

        #region 消息设置
        /// <summary>
        /// 创建或修改消息类型
        /// </summary>
        /// <param name="input"></param>
        public ResultMessage CreateOrUpdateAffair(AffairRemindDto input)
        {
            ResultMessage resultMessage = new ResultMessage();
            try
            {
                if (input.Id != null)
                {
                    var affair = _affairRemindRepository.Get(input.Id.Value);
                    affair.RoleList = input.RoleList;
                    affair.RoleListDesc = input.RoleListDesc;
                    affair.IsOpen = input.IsOpen;
                    affair.Isdefault = input.Isdefault;
                    _affairRemindRepository.Update(affair);
                    resultMessage.code = 0;
                }
                else
                {
                    AffairRemind temp = new AffairRemind();
                    temp.AffairCode = input.AffairCode;
                    temp.AffairType = input.AffairType;
                    temp.RoleList = temp.RoleList;
                    temp.RoleListDesc = input.RoleListDesc;
                    temp.IsOpen = input.IsOpen;
                    temp.Isdefault = input.Isdefault;
                    _affairRemindRepository.Insert(temp);
                    resultMessage.code = 0;
                }
                return resultMessage;
            }
            catch (Exception ex)
            {
                resultMessage.code = 1;
                resultMessage.Message = ex.Message;
                return resultMessage;
            }
        }
        /// <summary>
        /// 获取消息设置
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public PagedResultDto<AffairTmep> GetAffairTy(AffairInput input)
        {
            var query = from temp in _affairRemindRepository.GetAll()
                        select new AffairTmep
                        {
                            Id = temp.Id,
                            AffairCode = temp.AffairCode,
                            AffairType = temp.AffairType,
                            RoleList = temp.RoleList,
                            RoleListDesc = temp.RoleListDesc,
                            IsOpenDesc = temp.IsOpen == true ? "开启" : "关闭",
                            IsOpen = temp.IsOpen,
                            IsdefaultDesc = temp.Isdefault == true ? "开启" : "关闭",
                            Isdefault = temp.Isdefault
                        };
            int count = query.Count();
            query = query.PageBy(input);
            return new PagedResultDto<AffairTmep>(count, query.ToList());
        }
        /// <summary>
        /// 获取系统内所有的角色
        /// </summary>
        /// <returns></returns>
        public async Task<ListResultDto<RoleListDto>> GetAffairRoles()
        {
            GetRolesInput input = new GetRolesInput();
            input.Permission = "";
            var tempList= await _iRoleAppService.GetRoles(input);
            if (tempList.Items.Count > 0)
            {
                var role57 = tempList.Items.Where(d => d.DisplayName.ToLower().Contains("mes57")).ToList();
                if (role57.Count > 0)
                {
                    return new ListResultDto<RoleListDto>(role57);
                }
                else
                {
                    return new ListResultDto<RoleListDto>();
                }
            }
            else
            {
                return new ListResultDto<RoleListDto>();
            }
        }
        /// <summary>
        /// 获取消息树结构
        /// </summary>
        /// <returns></returns>
        public AffairTree GetAffairTree()
        {

            var currentUser = GetCurrentUser();
            AffairTree tree = new AffairTree();
            AffairTree children = new AffairTree();
            children.AffairDesc = "审批消息";
            children.Id = -1;
            children.nodeLevel = 1;
            children.Conut = _affairMessageRepository.Count(d => d.IsWorkFlow == true && d.ReadState == (ChatMessageReadState)1 && d.TargetUserId == currentUser.Id);
            tree.children.Add(children);
            AffairTree SystemAudit = new AffairTree();
            SystemAudit.AffairDesc = "系统消息";
            SystemAudit.nodeLevel = 1;

            List<AffairMessage> affairMessages = new List<AffairMessage>();
            var currentRoles = _userRoleRepository.GetAll().Where(userRole => userRole.UserId == currentUser.Id).Select(userRole => userRole.RoleId).ToArray();
            if (currentRoles.Length > 0)
            {
                string[] bigArr = Array.ConvertAll(currentRoles, _ => _.ToString());
                var tempArr = _affairMessageRepository.GetAll().Where(d => !string.IsNullOrEmpty(d.RoleId) && d.ReadState == (ChatMessageReadState)1 && d.IsWorkFlow == false && d.TargetUserId == null);
                foreach (var item in tempArr)
                {
                    var smallArr = item.RoleId.Split(',').ToArray();
                    //var exceptArr = bigArr.Except(smallArr);
                    var exceptArr = bigArr.Intersect(smallArr);
                    if (exceptArr.Any())
                    {
                        affairMessages.Add(item);
                    }
                }
                var tempTarget = _affairMessageRepository.GetAll().Where(d => d.ReadState == (ChatMessageReadState)1 && d.IsWorkFlow == false && (d.TargetUserId == GetCurrentUser().Id)).OrderByDescending(d => d.CreationTime);
                affairMessages.AddRange(tempTarget);
                affairMessages = affairMessages.Distinct().ToList();
            }
            else
            {
                affairMessages = _affairMessageRepository.GetAll().Where(d => d.ReadState == (ChatMessageReadState)1 && d.IsWorkFlow == false && (d.TargetUserId == GetCurrentUser().Id)).OrderByDescending(d => d.CreationTime).ToList();
            }

            var query = (from affair in _affairRemindRepository.GetAll()
                         join affairMessage in affairMessages.Distinct() on affair.Id equals affairMessage.AffairRemindId
                         where affairMessage.IsWorkFlow == false && affairMessage.ReadState == (ChatMessageReadState)1
                         group affairMessage by new { affairMessage.AffairRemindId, affair.AffairType } into g
                         select new { Id = g.Key.AffairRemindId, AffairDesc = g.Key.AffairType, Count = g.Count() }).ToList();
            if (query.Count > 0)
            {
                foreach (var item in query)
                {
                    AffairTree tempAudit = new AffairTree();
                    tempAudit.Id = item.Id;
                    tempAudit.nodeLevel = 2;
                    tempAudit.AffairDesc = item.AffairDesc;
                    tempAudit.Conut = item.Count;
                    SystemAudit.children.Add(tempAudit);
                }
            }
            tree.children.Add(SystemAudit);



            return tree;
        }
        /// <summary>
        /// 根据消息类别Id 获取消息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public PagedResultDto<AffairMessageDto> GetAffairMessagesByRemindId(AffairMessageSelectInput input)
        {
            var currentUser = GetCurrentUser();
            List<AffairMessageDto> affairs = new List<AffairMessageDto>();
            int count = 0;
            if (input.Id == -1)
            {

                affairs = (from affair in _affairMessageRepository.GetAll().Where(d => d.IsWorkFlow == true && d.TargetUserId == currentUser.Id)
                           orderby affair.ReadState,affair.CreationTime descending
                           select new AffairMessageDto
                           {
                               Id = affair.Id,
                               Title = affair.Title,
                               Message = affair.Message,
                               CreateTime = affair.CreationTime,
                               ReadState = affair.ReadState,
                               ReadStateDesc = GetEnumDesc(affair.ReadState),
                               SharedMessageId = affair.SharedMessageId
                           }).ToList();
               
                affairs = affairs.AsQueryable().WhereIf(input.ReadState != null, d => d.ReadState == input.ReadState).ToList();
                if (affairs.Count > 0)
                {
                    count = affairs.Count();
                    affairs = affairs.AsQueryable().PageBy(input).ToList();
                }
            }
            else
            {
                List<AffairMessage> affairMessages = new List<AffairMessage>();
                var currentRoles = _userRoleRepository.GetAll().Where(userRole => userRole.UserId == currentUser.Id).Select(userRole => userRole.RoleId).ToArray();
                if (currentRoles.Length > 0)
                {
                    string[] bigArr = Array.ConvertAll(currentRoles, _ => _.ToString());
                    var tempArr = _affairMessageRepository.GetAll().Where(d => !string.IsNullOrEmpty(d.RoleId) && d.IsWorkFlow == false && d.TargetUserId == null);
                    foreach (var item in tempArr)
                    {
                        var smallArr = item.RoleId.Split(',').ToArray();
                        var exceptArr = bigArr.Intersect(smallArr);
                        if (exceptArr.Any())
                        {
                            affairMessages.Add(item);
                        }
                    }
                    var tempTarget = _affairMessageRepository.GetAll().Where(d => (d.TargetUserId == GetCurrentUser().Id) && d.IsWorkFlow == false).OrderByDescending(d => d.CreationTime);
                    affairMessages.AddRange(tempTarget);
                    affairMessages = affairMessages.Distinct().ToList();
                }
                else
                {
                    affairMessages = _affairMessageRepository.GetAll().Where(d => (d.TargetUserId == GetCurrentUser().Id) && d.IsWorkFlow == false).OrderByDescending(d => d.CreationTime).ToList();
                }

                affairs = (from affair in affairMessages.Distinct()
                           orderby affair.ReadState, affair.CreationTime descending
                           select new AffairMessageDto
                           {
                               Id = affair.Id,
                               AffairRemindId = affair.AffairRemindId,
                               Title = affair.Title,
                               Message = affair.Message,
                               CreateTime = affair.CreationTime,
                               ReadState = affair.ReadState,
                               ReadStateDesc = GetEnumDesc(affair.ReadState),
                               SharedMessageId = affair.SharedMessageId
                           }).OrderByDescending(d => d.CreateTime).OrderBy(d => d.ReadState).ToList();
               
                affairs = affairs.AsQueryable().WhereIf(input.Id != null, d => d.AffairRemindId == input.Id).WhereIf(input.ReadState != null, d => d.ReadState == input.ReadState).ToList();
                if (affairs.Count > 0)
                {
                    count = affairs.Count();
                    affairs = affairs.AsQueryable().PageBy(input).ToList();
                }

            }
            return new PagedResultDto<AffairMessageDto>(count, affairs);
        }




        /// <summary>
        /// 根据Id获取单个消息信息
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public AffairRemindDto GetAffairById(int id)
        {
            return ObjectMapper.Map<AffairRemindDto>(_affairRemindRepository.Get(id));
        }
        ///// <summary>
        ///// 查询所有信息
        ///// </summary>
        ///// <param name="affairRemindDto"></param>
        ///// <returns></returns>
        //public PagedResultDto<AffairRemind> GetAffairList(AffairRemindDto affairRemindDto)
        //{
        //    var query = _affairRemindRepository.GetAll();
        //    int count = query.Count();
        //    var codeList = query.PageBy(affairRemindDto).ToList();
        //    return new PagedResultDto<AffairRemind>(count, codeList);
        //}
        #endregion

        #region 消息通知
        /// <summary>
        /// 查询各个类型的消息及未读信息数量
        /// </summary>
        /// <param name="IsWorkFlow"></param>
        /// <returns></returns>
        public List<AffairStatisticsDto> GetAffairStatistics(bool IsWorkFlow)
        {
            if (IsWorkFlow == false)
            {
                var result = from affairMsg in _affairMessageRepository.GetAll()
                             join affairRemind in _affairRemindRepository.GetAll() on affairMsg.AffairRemindId equals affairRemind.Id
                             where affairMsg.IsWorkFlow == false && affairMsg.ReadState == (ChatMessageReadState)1
                             orderby affairMsg.CreationTime descending
                             group affairMsg by new { affairRemind.AffairType, affairRemind.Id } into affairResult
                             select new AffairStatisticsDto { AffairType = affairResult.Key.AffairType, Id = affairResult.Key.Id, Conut = affairResult.Count() };
                return result.ToList();
            }
            else
            {
                AffairStatisticsDto affairStatisticsDto = new AffairStatisticsDto();
                affairStatisticsDto.Id = 0;
                affairStatisticsDto.AffairType = "审批消息";
                affairStatisticsDto.Conut = _affairMessageRepository.Count(d => d.IsWorkFlow == true && d.ReadState == (ChatMessageReadState)1);
                List<AffairStatisticsDto> list = new List<AffairStatisticsDto>();
                list.Add(affairStatisticsDto);
                return list;
            }
        }

        /// <summary>
        /// 根据消息guid获取消息具体内容
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public AffairMessage GetAffairMessageById(Guid guid)
        {
            return _affairMessageRepository.FirstOrDefault(d => d.Id == guid);
        }

        /// <summary>
        /// 根据Id删除消息
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public bool DeleteAffairMessageById(Guid Id)
        {
            var affairMessage = _affairMessageRepository.FirstOrDefault(Id);
            if (affairMessage != null)
            {
                _affairMessageRepository.Delete(affairMessage);
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 标记已读 
        /// </summary>
        /// <param name="guid"></param>
        /// <param name="chatMessageReadState"></param>
        /// <returns></returns>
        public bool UpdateAffairMessageById(Guid guid)
        {
            var affairMessage = _affairMessageRepository.FirstOrDefault(guid);
            if (affairMessage != null)
            {
                affairMessage.ChangeReadState((ChatMessageReadState)2);
                affairMessage.ReceiveTime = DateTime.Now;
                _affairMessageRepository.Update(affairMessage);
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 批量标记已读
        /// </summary>
        /// <param name="IdList"></param>
        public ResultMessage UpdateBatchAffairMessage(List<Guid> IdList)
        {
            ResultMessage resultMessage = new ResultMessage();
            try
            {
                var query = from temp in _affairMessageRepository.GetAll()
                            join temp2 in IdList on temp.Id equals temp2
                            select temp;
                foreach (var item in query)
                {
                    item.ChangeReadState((ChatMessageReadState)2);
                    item.ReceiveTime = DateTime.Now;
                    _affairMessageRepository.Update(item);

                }
                resultMessage.code = 0;
                return resultMessage;
            }
            catch (Exception ex)
            {
                resultMessage.code = 1;
                resultMessage.Message = ex.Message;
                return resultMessage;
            }
        }
        /// <summary>
        /// 批量删除消息
        /// </summary>
        /// <param name="IdList"></param>
        public ResultMessage DeleteBatchAffairMessage(List<Guid> IdList)
        {
            ResultMessage resultMessage = new ResultMessage();
            try
            {
                var query = from temp in _affairMessageRepository.GetAll()
                            join temp2 in IdList on temp.Id equals temp2
                            select temp;
                foreach (var item in query)
                {
                    _affairMessageRepository.Delete(item);

                }
                resultMessage.code = 0;
                return resultMessage;
            }
            catch (Exception ex)
            {
                resultMessage.code = 1;
                resultMessage.Message = ex.Message;
                return resultMessage;
            }
        }


        #endregion


        #region 系统相关
        /// <summary>
        /// 查询当前角色的未读的消息列表
        /// </summary>
        public List<AffairMessage> GetMessages()
        {
            List<AffairMessage> affairMessages = new List<AffairMessage>();
            var currentUser = GetCurrentUser();

            var currentRoles = _userRoleRepository.GetAll()
              .Where(userRole => userRole.UserId == currentUser.Id)
              .Select(userRole => userRole.RoleId).ToArray();
            if (currentRoles.Length > 0)
            {
                string[] bigArr = Array.ConvertAll(currentRoles, _ => _.ToString());
                var tempArr = _affairMessageRepository.GetAll().Where(d => !string.IsNullOrEmpty(d.RoleId) && d.ReadState == (ChatMessageReadState)1 && d.TargetUserId == null);
                foreach (var item in tempArr)
                {
                    var smallArr = item.RoleId.Split(',').ToArray();
                    var exceptArr = bigArr.Intersect(smallArr);
                    if (exceptArr.Any())
                    {
                        affairMessages.Add(item);
                    }
                }
                var tempTarget = _affairMessageRepository.GetAll().Where(d => d.ReadState == (ChatMessageReadState)1 && (d.TargetUserId == GetCurrentUser().Id));
                affairMessages.AddRange(tempTarget);
                affairMessages = affairMessages.Distinct().OrderByDescending(d => d.CreationTime).ToList();
            }
            else
            {
                affairMessages = _affairMessageRepository.GetAll().Where(d => d.ReadState == (ChatMessageReadState)1 && (d.TargetUserId == GetCurrentUser().Id)).OrderByDescending(d => d.CreationTime).ToList();

            }

            return affairMessages;
        }
        /// <summary>
        /// 标记全部已读
        /// </summary>
        /// <param name="IdList"></param>
        public void MarkAllRead(List<Guid> IdList)
        {
            var tempData = _affairMessageRepository.GetAll().Where(d => IdList.Contains(d.Id));
            foreach (var item in tempData)
            {
                item.ChangeReadState(ChatMessageReadState.Read);
                item.ReceiveTime = DateTime.Now;
                _affairMessageRepository.Update(item);
            }
        }
        #endregion
        private static string GetEnumDesc(System.Enum parm)
        {
            FieldInfo enumInfo = parm.GetType().GetField(parm.ToString());
            if (enumInfo == null)
            {
                return "";
            }
            DescriptionAttribute[] enumAttributes
                = (DescriptionAttribute[])enumInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (enumAttributes.Length > 0)
            {
                return enumAttributes[0].Description;
            }
            return parm.ToString();
        }

    }
}
